package com.badshun.map;

import com.badlogic.gdx.maps.tiled.*;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.maps.tiled.renderers.*;
import com.badlogic.gdx.physics.box2d.*;
import com.badlogic.gdx.math.*;
import com.badshun.box2d.*;
import com.badlogic.gdx.maps.*;
import com.badlogic.gdx.utils.*;

public class GameMap {
	public TiledMap map;
	
	private OrthographicCamera camera;
	private OrthogonalTiledMapRenderer render;
	
	private Box2DWorld world;
	
	private Body tiledBody;
	
	private Fixture fTile;
	private Fixture fDoor;
	
	public String TAG;
	
	public GameMap(String path,String TAG,Box2DWorld world,OrthographicCamera camera) {
		this.world = world;
		this.camera = camera;
		
		defineMap(path,TAG);
	}
	
	private void defineMap(String path,String TAG) {
		map = new TmxMapLoader().load(path);
		
		render = new OrthogonalTiledMapRenderer(map);
		
		createLayerWithBox2D(TAG);
	}
	
	private void createLayerWithBox2D(String TAG) {
		MapObjects objs = map.getLayers().get("cannotpass").getObjects();

		BodyDef bdef = new BodyDef();
        bdef.type = BodyDef.BodyType.StaticBody;
		
        ChainShape shape = new ChainShape();
        FixtureDef fdef = new FixtureDef();
		
		final int tileSize = 32;

        for (int i = 0; i < objs.getCount(); i++) {
			MapObject obj = objs.get(i);
			
			float x = obj.getProperties().get("x");
			float y = obj.getProperties().get("y");
			
            bdef.position.set(x / 2 + tileSize / 2,y / 2 + tileSize / 2);
            tiledBody = world.world.createBody(bdef);
			tiledBody.setUserData(TAG);

            Vector2[] chain = {
				new Vector2(x / 2 - tileSize / 2, y / 2 + tileSize / 2),
				new Vector2(x / 2 + tileSize / 2, y / 2 + tileSize / 2),
				new Vector2(x / 2 + tileSize / 2, y / 2 - tileSize / 2),
				new Vector2(x / 2 - tileSize / 2, y / 2 - tileSize / 2),
				new Vector2(x / 2 - tileSize / 2, y / 2 + tileSize / 2)
            };

            shape.createChain(chain);

            fdef.shape = shape;
			fdef.filter.categoryBits = 8;
			fdef.filter.maskBits = 2 | 4 | 16;
			
			fTile = tiledBody.createFixture(fdef);
			fTile.setUserData("TILE");
		}
		
		MapObjects doors = map.getLayers().get("door").getObjects();
		
		for (int i = 0; i < doors.getCount(); i++) {
			MapObject door = doors.get(i);

			float x = door.getProperties().get("x");
			float y = door.getProperties().get("y");

            bdef.position.set(x / 2 + tileSize / 2,y / 2 + tileSize / 2);
            Body tiledBody = world.world.createBody(bdef);
			tiledBody.setUserData(TAG + "DOOR");

            Vector2[] chain = {
				new Vector2(x / 2 - tileSize / 2, y / 2 + tileSize / 2),
				new Vector2(x / 2 + tileSize / 2, y / 2 + tileSize / 2),
				new Vector2(x / 2 + tileSize / 2, y / 2 - tileSize / 2),
				new Vector2(x / 2 - tileSize / 2, y / 2 - tileSize / 2),
				new Vector2(x / 2 - tileSize / 2, y / 2 + tileSize / 2)
            };

            shape.createChain(chain);

            fdef.shape = shape;
			fdef.filter.categoryBits = 8;
			fdef.filter.maskBits = 2 | 4;
			
			fdef.isSensor = true;

			fDoor = tiledBody.createFixture(fdef);
			fDoor.setUserData("DOOR");
		}
		
	}
	
	public void destroyBody(String TAG) {
		Array<Body> bArray = new Array<Body>();
		
		world.world.getBodies(bArray);
		
		for(int i = 0; i < bArray.size; i++) {
			Body body = bArray.get(i);
			
			if(body.getUserData() != null) {
				if(body.getUserData().equals(TAG) || body.getUserData().equals(TAG + "DOOR") || body.getUserData().equals(TAG + "NPC")) {
					Array<Fixture> fArray = body.getFixtureList();
					
					for(int j = 0; i < fArray.size; j++) {
						body.destroyFixture(fArray.get(j));
					}
					
					world.world.destroyBody(body);
				}
			}
		}
	}
	
	public void render() {
		camera.update();
		
		render.setView(camera);
		render.render();
	}
}
